/*
 * BitMapAddressedSet.h
 *
 *  Created on: 18/09/2012
 *      Author: marcio
 */

#ifndef BITMAPDIRECTLYADDRESSEDSET_H_
#define BITMAPDIRECTLYADDRESSEDSET_H_

#include "DirectlyAddressedSet.h"
#include "BitTools.h"
#include "Hash.h"
#include <stdio.h>


/*! \class Filter
 * \brief It provides the ability of filtering the enumeration of a DirectlyAddressedSet.
 *
 * When a DirectlyAddressedSet is provided with a Filter, the enumeration only considers the keys in the filter.
 *
 * \tparam T the type of each node of the filtered DirectlyAddressedSet
 */
template <typename T>
class Filter {

public:

	/*!
	 * \brief Constructor of a  filter whose elements are described by a vEBTree.
	 */
	Filter() {};
	/*!
	 * \brief Destructor.
	 */
	virtual ~Filter() {};
	/*!
	 * \brief Performs the filtering of the specified word
	 *
	 * \param res resulting word, after filtering
	 * \param w1 the word of the set to be filtered
	 * \param w2 the word of this filter
	 */
	virtual void filter(T * res, const T * w1, const T * w2) const = 0;
};

/*!
 * \class AndFilter
 *
 * \brief Filter for thelogic operation \c and
 */
template <typename T>
class AndFilter : public Filter<T> {
public:
	AndFilter() {};
	void filter(T * res, const T * w1, const T * w2) const { *res = *w1 & *w2; };
};

/*!
 * \class OrFilter
 *
 * \brief Filter for the logic operation \c or
 */
template <typename T>
class OrFilter : public Filter<T> {
public:
	OrFilter() {};
	void filter(T * res, const T * w1, const T * w2) const { *res = *w1 | *w2; };
};

/*!
 * \class XorFilter
 *
 * \brief Filter for the logic operation \c xor
 */
template <typename T>
class XorFilter : public Filter<T> {
public:
	XorFilter() {};
	void filter(T * res, const T * w1, const T * w2) const { *res = *w1 ^ *w2; };
};

/*!
 * \class AndNegFilter
 *
 * \brief Filter for the logic operation \c and of the first parameter and the negation of the second parameter
 */
template <typename T>
class AndNegFilter : public Filter<T> {
public:
	AndNegFilter() {};
	void filter(T * res, const T * w1, const T * w2) const { *res = *w1 & ~(*w2); };
};

/*!
 * \class BitMapDirectlyAddressedSet
 *
 * \brief A DirectlyAddressedSet implemented with an array of nodes, each node corresponding to a word of the specified type.
 *
 * It is an implementation of the abstract class DirectlyAddressedSet assuming a linear
 * array of bits as the data structure, implementing iterators. In such an implementation, each key acts as an index in the array.
 * More precisely, key \f$i\f$ corresponds to the \f$(i \mbox{ mod } b)\f$-least significant bit of the \f$(\lfloor i/b \rfloor)\f$-th
 * node of the array, where \f$b\f$ is the size of a node.
 *
 * This class is designed to be used with any implementation of the array of bits. Typically, two possible implementations are vectors
 * and hash tables of nodes.
 *
 * \tparam the type of the array, defining \f$b\f$ as \c sizeof(T).
 */
template<typename T>
class BitMapDirectlyAddressedSet : public DirectlyAddressedSet, protected BitTools<T> {
	class BitMapDirectlyAddressedSets;

public:
	/*! \class BitMapDirectlyAddressedSet::BitMapIterator
	 * \brief An abstract implementation of DirectlyAddressedSet::Iterator
	 *
	 */
	class BitMapIterator : public DirectlyAddressedSet::Iterator, protected BitTools<T> {
		friend class BitMapDirectlyAddressedSet;
	protected:
		T *					node;		//!< current node
		long				inode;		//!< index of the node in the array
		long				dspl;		//!< first value in the current node
		long  				cursor;		//!< cursor position in the current node

		BitMapDirectlyAddressedSet<T> * const t;	//!< the enclosing BitMapDirectlyAddressedSet<T>, which gives access to BitMapDirectlyAddressedSet<T>::treeNode method

		/*!
		 *  \brief A constructor for a specified enclosed BitMapDirectlyAddressedSet<T>.
		 *
		 *  \param t the enclosing abstract set
		 */
		BitMapIterator(BitMapDirectlyAddressedSet<T> * t);

	public:
		//destructor
		~BitMapIterator();

		/*!
		 * \brief Generic implementation for bitmaps.
		 *
		 * This implementation can be employed with any implementation of bitmaps. It requires the node of index
		 * \f$\lfloor i/b \rfloor\f$, even if it empty.
		 *
		 * \param i the specified value
		 */
		virtual void restartFrom(long i);
		/*!
		 * \brief Generic implementation for bitmaps.
		 *
		 * This implementation can be employed with any implementation of bitmaps.
		 *
		 * \return the next key to be enumerated, if there is one, or a value greater than all values in the universe otherwise
		 */
		virtual long next();
		/*!
		 * \brief Generic implementation for bitmaps.
		 *
		 * This implementation can be employed with any implementation of bitmaps. The price to pay is the need for two
		 * comparisons: one for the specified limit of the enumeration, and another for the end of a node (typically, the
		 * query for a 1-bit in a node returns -1 in case of failure).  In the case when this method is used
		 * to enumerate a particular node of a level of a tree of bitmaps, a more specialized implementation could perform only
		 * the latter of these comparisons.
		 *
		 * \param to the value to limit the enumeration
		 *
		 * \return the next key to be enumerated up to the specified value, if there is one, or a value greater than
		 * or equal to the specified value otherwise
		 *
		 * \see DirectlyAddressedSets
		 */
		virtual long nextUpTo(long to);
	};

	class FilteredBitMapIterator : public BitMapIterator {
		friend class BitMapDirectlyAddressedSet;

	private :
		Filter<T> * 			f;		//!< the filter
		const BitMapIterator * 	fiter;	//!< the BitMapDirectlyAddressedSet<T> used to filter
		T 						fnode;	//!< filtered node
		FilteredBitMapIterator(BitMapDirectlyAddressedSet<T> * set, BitMapIterator * fiter, Filter<T> * fil);

	protected:

	public:

		~FilteredBitMapIterator(){};

		void restartFrom(long i);
		long nextUpTo(long to);
	};

	class ComplIterator : public BitMapIterator {
		friend class BitMapDirectlyAddressedSet;

	private :
		T cnode;				//!< complement of current node
		ComplIterator(BitMapDirectlyAddressedSet<T> * set);

	public:

		~ComplIterator();

		void restartFrom(long i);
		long nextUpTo(long to);
	};

protected:

	long 	sizeT;	//<! the size of the bitmap, in words

	/*!
	 * \brief Determines the node of this array for enumeration of 1-bits with specified index.
	 *
	 * This method implements the data structure used to store the nodes of this array.
	 *
	 * \param i the index
	 *
	 * \return the node corresponding to the specified index
	 */
	virtual T * arrayNode(long i) const = 0;

	/*!
	 * \brief A simple constructor.
	 *
	 * Computes the size of the array and allocates the corresponding memeory space.
	 *
	 * \param u the size of the universe
	 */
	 BitMapDirectlyAddressedSet(long u);


public:

	/*!
	 * \brief The simple destructor
	 *
	 * Free the memory used.
	 *
	 */
	 ~BitMapDirectlyAddressedSet();

	 /*!
	  * \brief Create a copy of the current object.
	  *
	  * Copy the whole vector of bits to a other structure.
	  *
	  * \return a copy if the current object.
	  */
	 virtual DirectlyAddressedSet* clone() const = 0;
	 virtual DirectlyAddressedSet::Iterator* newIterator();
	 virtual DirectlyAddressedSet::Iterator* newComplIterator();

	 /*!
	  * \brief An Iterator for the set represented by the object with a filter.
	  *
	  * Return an iterator to enumerate all the keys of
	  * the set represented by this object and the filter specified as a parameter.
	  *
	  * \param d the DirectlyAddressedSet to filter the enumeration.
	  * \param f the filter determining the operation of filtering
	  *
	  * \return an iterator to the set
	  */
	 virtual DirectlyAddressedSet::Iterator* newIterator(BitMapDirectlyAddressedSet<T> * d, Filter<T> * f);

	 /*!
	  * \brief Adds the specified key to the set.
	  *
	  * Set the bit in the specified position to 1. This method is optimal and if the
	  * specified position is in a node not in the array, then an error will occur.
	  *
	  * \param i the specified key.
	  */
	 virtual void toSet(long i);

	 /*!
	  * \brief Removes the specified key from the set.
	  *
	  *	Sets the bit in the specified position to 0. This method is optimal and if the
	  * specified position is in a node not in array, then an error will occur.
	  *
	  * \param i the specified key
	  */
	 virtual void toCompl(long i);

	 /*!
	  * \brief Swap a element between the set and the complement.
	  *
	  * \param i the especified element.
	  */
	 virtual void flip(long i);

	 /*!
	  * \brief Verify if a element of the universe is in the set.
	  *
	  * Verify if the bit in the specified position is 1. This method is optmal and if the
	  * especified position is out of the vector range an error will occur.
	  *
	  * \param i the specified element
	  *
	  * \return true if i belongs to the set and false otherwise
	  */
	 virtual bool isInSet(long i) const;

	 /*!
	  * \brief Create a vector of the elements in the set
	  *
	  * \param size a pointer to store the size of the set.
	  *
	  * \return a array contains all the elements of the set.
	  */
	 virtual char * toArray(long* size) = 0;

	 /*!
	  * \brief Add all the elements in the universe to the set
	  *
	  * Implemented with a C function memset.
	  *
	  * \see memset()
	  *
	  */
	 virtual void allToSet() = 0;

	 /*!
	  * \brief Remove all the elements of the set.
	  *
	  * Implemented with a C function memset.
	  *
	  * \see memset()
	  */
	 virtual void allToCompl() = 0;

	 /*!
	  * \brief The complement of the current set
	  *
	  * Implemented as a linear search in each word of the vector.
	  */
	 virtual void flipAll() = 0;

	 /*!
	  * \brief Adds to this set all the elements in the union of two specified sets
	  *
	  * \param v one set to be operated
	  * \param w the other set
	  *
	  * \see addAll()
	  */
	 virtual void unionOf(DirectlyAddressedSet * v, DirectlyAddressedSet * w);

	 /*!
	  * \brief Adds to this set all the elements in the symmetric difference of two specified sets
	  *
	  * \param v one set to be operated
	  * \param w the other set
	  *
	  * \see symDiff()
	  */
	 virtual void symDiffOf(DirectlyAddressedSet * v, DirectlyAddressedSet * w);

	 /*!
	  * \brief Adds to this set all the elements in the intersection of two specified sets
	  *
	  * \param v one set to be operated
	  * \param w the other set
	  *
	  * \see retainAll()
	  */
	 virtual void intersectOf(DirectlyAddressedSet * v, DirectlyAddressedSet * w);

	 /*!
	  * \brief Adds to this set all the elements in the difference of two specified sets
	  *
	  * \param v one set to be operated
	  * \param w the other set
	  *
	  * \see removeAll()
	  */
	 virtual void diffOf(DirectlyAddressedSet * v, DirectlyAddressedSet * w);

	 //DEBUG
	 virtual void show();

};

template<typename T>
inline BitMapDirectlyAddressedSet<T>::BitMapDirectlyAddressedSet(long u) : DirectlyAddressedSet(u) {
	sizeT = (u + this->word_size - 1) >> this->logb;
}

template<typename T>
inline BitMapDirectlyAddressedSet<T>::~BitMapDirectlyAddressedSet() {
}

template<typename T>
inline BitMapDirectlyAddressedSet<T>::BitMapIterator::BitMapIterator(BitMapDirectlyAddressedSet<T> * t) : BitTools<T>(), t(t) {
	restart();
}

template<typename T>
inline BitMapDirectlyAddressedSet<T>::BitMapIterator::~BitMapIterator() {};

template<typename T>
inline void BitMapDirectlyAddressedSet<T>::BitMapIterator::restartFrom(long i) {
	cursor = this->remainder(i);
	inode = this->quotient(i);
	node = t->arrayNode(inode);
	dspl = i - cursor;
	if ((*node & (1LL << cursor)) == 0x00) {
		cursor = builtinNextLeast(*node, cursor);
		while (cursor < 0 && dspl < u) {
			dspl += sizeof(T);
			node = t->arrayNode(++inode);
			cursor = builtinLeast(*node);
		}
	}
}

template<typename T>
inline long BitMapDirectlyAddressedSet<T>::BitMapIterator::next() {
	return nextUpTo(u);
}

template<typename T>
inline long BitMapDirectlyAddressedSet<T>::BitMapIterator::nextUpTo(long to) {
	long ret = dspl + cursor;
	cursor = builtinNextLeast(*node, cursor);
	if (cursor < 0) {
		while (cursor < 0 && dspl < to) {
			dspl += sizeof(T);
			node = t->arrayNode(++inode);
			cursor = builtinLeast(*node);
		}
		if (cursor < 0)
			cursor = 0;
	}

	return ret;
}

template<typename T>
inline BitMapDirectlyAddressedSet<T>::FilteredBitMapIterator::FilteredBitMapIterator(BitMapDirectlyAddressedSet<T> * set, BitMapIterator * fiter, Filter<T> * fil) : BitMapIterator(set), fiter(fiter), f(fil) {
}

template<typename T>
inline void BitMapDirectlyAddressedSet<T>::FilteredBitMapIterator::restartFrom(long i) {
	this->cursor = this->remainder(i);
	this->inode = this->quotient(i);
	this->dspl = i - this->cursor;

	f->filter(&fnode, this->t->arrayNode(this->inode), fiter->t->arrayNode(this->inode));
	if ((fnode & (1LL << this->cursor)) == 0x00) {
		this->cursor = builtinNextLeast(fnode, this->cursor);
		while (this->cursor < 0 && this->dspl < u) {
			this->dspl += sizeof(T);
			f->filter(&fnode, this->t->arrayNode(++this->inode), fiter->t->arrayNode(this->inode));
			this->cursor = builtinLeast(fnode);
		}
	}
}

template<typename T>
inline long BitMapDirectlyAddressedSet<T>::FilteredBitMapIterator::nextUpTo(long to) {
	long ret = this->dspl + this->cursor;
	this->cursor = builtinNextLeast(fnode, this->cursor);
	if (this->cursor < 0) {
		while (this->cursor < 0 && this->dspl < to) {
			this->dspl += sizeof(T);
			f->filter(&fnode, this->t->arrayNode(++this->inode), fiter->t->arrayNode(this->inode));
			this->cursor = builtinLeast(fnode);
		}
		if (this->cursor < 0)
			this->cursor = 0;
	}

	return ret;
}

template<typename T>
inline BitMapDirectlyAddressedSet<T>::ComplIterator::ComplIterator(BitMapDirectlyAddressedSet<T> * t) : Iterator(t) {
}

template<typename T>
inline BitMapDirectlyAddressedSet<T>::ComplIterator::~ComplIterator() {};

template<typename T>
inline void BitMapDirectlyAddressedSet<T>::ComplIterator::restartFrom(long i) {
	this->cursor = this->remainder(i);
	this->inode = this->quotient(i);
	cnode = ~(*this->t->arrayNode(this->inode));
	this->dspl = i - this->cursor;
	if ((cnode & (1LL << this->cursor)) == 0x00) {
		this->cursor = builtinNextLeast(cnode, this->cursor);
		while (this->cursor < 0 && this->dspl < u) {
			this->dspl += sizeof(T);
			cnode = ~(*this->t->arrayNode(++this->inode));
			this->cursor = builtinLeast(cnode);
		}
	}
}

template<typename T>
inline long BitMapDirectlyAddressedSet<T>::ComplIterator::nextUpTo(long to) {
	long ret = this->dspl + this->cursor;
	this->cursor = builtinNextLeast(cnode, this->cursor);
	if (this->cursor < 0) {
		while (this->cursor < 0 && this->dspl < to) {
			this->dspl += sizeof(T);
			cnode = ~(*this->t->arrayNode(++this->inode));
			this->cursor = builtinLeast(cnode);
		}
		if (this->cursor < 0)
			this->cursor = 0;
	}

	return ret;
}

template<typename T>
inline DirectlyAddressedSet::Iterator * BitMapDirectlyAddressedSet<T>::newIterator() {
	return new BitMapIterator(this);
}

template<typename T>
inline DirectlyAddressedSet::Iterator* BitMapDirectlyAddressedSet<T>::newIterator(BitMapDirectlyAddressedSet<T> * d, Filter<T> * f) {
	return new FilteredBitMapIterator(this, d->newIterator(), f);
}

template<typename T>
inline DirectlyAddressedSet::Iterator* BitMapDirectlyAddressedSet<T>::newComplIterator(){
	return new ComplIterator(this);
}

template <typename T>
inline void BitMapDirectlyAddressedSet<T>::toSet(long i) {
	*arrayNode(this->quotient(i)) |= (1LL << this->remainder(i));
}

template <typename T>
inline void BitMapDirectlyAddressedSet<T>::toCompl(long i) {
	*arrayNode(this->quotient(i)) &= ~(1LL << this->remainder(i));
}

template<typename T>
inline void BitMapDirectlyAddressedSet<T>::flip(long i) {
	*arrayNode(this->quotient(i)) ^= (1LL << this->remainder(i));
}

template<typename T>
inline bool BitMapDirectlyAddressedSet<T>::isInSet(long i) const {
	return *arrayNode(this->quotient(i)) &= (1LL << this->remainder(i)) != 0;
}

template<typename T>
inline void BitMapDirectlyAddressedSet<T>::show() {
	printf("vetor \n");
	for(long i = 0; i < u; i++)
		if (isInSet(i))
			printf("<%lu> ", i);
	printf("\n");
}

/*!
 * \class ArrayBitMapDirectlyAddressedSet
 *
 * \brief A BitMapDirectlyAddressedSet implemented with an array of words.
 *
 * It is an implementation of the abstract class DirectlyAddressedSet with a linear
 * array as data structure, implementing iterators.
 *
 * \tparam the type of the array
 */
template<typename T>
class ArrayBitMapDirectlyAddressedSet : public BitMapDirectlyAddressedSet<T> {
	ArrayBitMapDirectlyAddressedSet(ArrayBitMapDirectlyAddressedSet<T> * set, long from, long to);

protected:

	T *	baseT;	//<! the array of words

	T * arrayNode(long i) const;

public:

	/*!
	 * \brief A simple constructor.
	 *
	 * Computes the size of the array and allocates the corresponding memeory space.
	 *
	 * \param u the size of the universe
	 */
	 ArrayBitMapDirectlyAddressedSet(long u);

	/*!
	 * \brief The simple destructor
	 *
	 * Free the memory used.
	 *
	 */
	 virtual ~ArrayBitMapDirectlyAddressedSet();

	 virtual DirectlyAddressedSet * subset(long from, long to) const;

	 /*!
	  * \brief Create a copy of the current object.
	  *
	  * Copy the whole vector of bits to a other structure.
	  *
	  * \return a copy if the current object.
	  */
	 virtual DirectlyAddressedSet* clone() const;

	 /*!
	  * \brief Create a vector of the elements in the set
	  *
	  * \param size a pointer to store the size of the set.
	  *
	  * \return a array contains all the elements of the set.
	  */
	 virtual char * toArray(long* size);

	 /*!
	  * \brief Add all the elements in the universe to the set
	  *
	  * Implemented with a C function memset.
	  *
	  * \see memset()
	  *
	  */
	 virtual void allToSet();

	 /*!
	  * \brief Remove all the elements of the set.
	  *
	  * Implemented with a C function memset.
	  *
	  * \see memset()
	  */
	 virtual void allToCompl();
	 virtual void flipAll();
	 virtual long cardOfSet();
	 virtual long cardOfCompl();

	 //DEBUG
	 virtual void show();

};

template<typename T>
ArrayBitMapDirectlyAddressedSet<T>::ArrayBitMapDirectlyAddressedSet(long u) : BitMapDirectlyAddressedSet<T>(u) {
	baseT = new T[this->sizeT];
	memset(baseT, 0, this->sizeT << this->logw);
}

template<typename T>
ArrayBitMapDirectlyAddressedSet<T>::ArrayBitMapDirectlyAddressedSet(ArrayBitMapDirectlyAddressedSet<T> * set, long from, long to) : BitMapDirectlyAddressedSet<T>(to-from) {
	baseT = &set->baseT[this->quotient(from)];
}

template<typename T>
ArrayBitMapDirectlyAddressedSet<T>::~ArrayBitMapDirectlyAddressedSet() {
	delete baseT;
}

template<typename T>
DirectlyAddressedSet * ArrayBitMapDirectlyAddressedSet<T>::subset(long from, long to) const {
	return new ArrayBitMapDirectlyAddressedSet<T>(this, from, to);
}

template<typename T>
T * ArrayBitMapDirectlyAddressedSet<T>::arrayNode(long i) const {
	return baseT + i;
}

template<typename T>
inline DirectlyAddressedSet* ArrayBitMapDirectlyAddressedSet<T>::clone() const {
	ArrayBitMapDirectlyAddressedSet<T>* ret = new ArrayBitMapDirectlyAddressedSet<T>(this->u);
	memcpy(ret->baseT, baseT, this->sizeT << this->logw);
	return ret;
}

template<typename T>
inline char * ArrayBitMapDirectlyAddressedSet<T>::toArray(long* size) {
	T* ret = new T[this->sizeT];
	memcpy(ret, baseT, this->sizeT << this->logw);
	return (char *) ret;
}

template<typename T>
inline void ArrayBitMapDirectlyAddressedSet<T>::allToSet() {
	memset(baseT, 0xFF, this->sizeT << this->logw);
}

template<typename T>
inline void ArrayBitMapDirectlyAddressedSet<T>::allToCompl() {
	memset(baseT, 0, this->sizeT << this->logw);
}

template<typename T>
inline void ArrayBitMapDirectlyAddressedSet<T>::flipAll() {
	T* vec, *lim;
	for(vec = baseT, lim = baseT + this->sizeT; vec < lim; vec++ ) *vec = ~(*vec);
}

template<typename T>
inline long ArrayBitMapDirectlyAddressedSet<T>::cardOfSet() {
	long ret = 0;
	T* vec, *lim;
	for(vec = baseT, lim = baseT + this->sizeT; vec < lim; vec++) {
		ret += this->builtinCounter(*vec);
	}
	return ret;
}

template<typename T>
inline long ArrayBitMapDirectlyAddressedSet<T>::cardOfCompl(){
	long ret;
	T* vec, *lim;
	for(vec = baseT, lim = baseT + this->sizeT; vec < lim; vec++){
		ret += this->builtinCounter(~*vec);
	}
	return ret;
}

template<typename T>
inline void ArrayBitMapDirectlyAddressedSet<T>::show() {
	printf("vetor \n");
	long i;
	for(i = 0; i < this->u; i++)
		if (this->isInSet(i))
			printf("<%lu> ", i);
	printf("\n");
}

/*!
 * \class HashDirectlyAddressedSet
 *
 * \brief A static BitMapDirectlyAddressedSet implemented with a perfect hash table.
 *
 * It is an implementation of the abstract class DirectlyAddressedSet with a perfect hash table
 * as data structure, implementing iterators.
 *
 * \tparam the type of the array
 */
template<typename T>
class HashBitMapDirectlyAddressedSet : public BitMapDirectlyAddressedSet<T> {
	friend class HashBitMapDirectlyAddressedSetFactory;

	T *				baseT;	//<! the array of nodes; it includes the node of index 0, even if it is empty, since it is required by restart() method
	Hash<long> * 	hash;	//!< function

	T * arrayNode(long i) const;
	 HashBitMapDirectlyAddressedSet(long u, const T * s, const long n);

public:
	 virtual ~HashBitMapDirectlyAddressedSet();
	 /*!
	  * \brief Not implemented since this set is static.
	  *
	  * An invocation to this method has no effect on the set.
	  */
	 virtual void toSet(long i) {};
	 /*!
	  * \brief Not implemented since this set is static.
	  *
	  * An invocation to this method has no effect on the set.
	  */
	 virtual void toCompl(long i) {};
	 /*!
	  * \brief Not implemented since this set is static.
	  *
	  * An invocation to this method has no effect on the set.
	  */
	 virtual void flip(long i) {};
	 /*!
	  * \brief Not implemented since this set is static.
	  *
	  * An invocation to this method has no effect on the set.
	  */
	 virtual void allToSet() {};
	 /*!
	  * \brief Not implemented since this set is static.
	  *
	  * An invocation to this method has no effect on the set.
	  */
	 virtual void allToCompl() {};
	 /*!
	  * \brief Not implemented since this set is static.
	  *
	  * An invocation to this method has no effect on the set.
	  */
	 virtual void flipAll() {};
	 /*!
	  * \brief Not implemented since this set is static.
	  *
	  * An invocation to this method has no effect on the set.
	  */
	 virtual void addAll(DirectlyAddressedSet * v) {};
	 /*!
	  * \brief Not implemented since this set is static.
	  *
	  * An invocation to this method has no effect on the set.
	  */
	 virtual void symDiff(DirectlyAddressedSet * v) {};
	 /*!
	  * \brief Not implemented since this set is static.
	  *
	  * An invocation to this method has no effect on the set.
	  */
	 virtual void removeAll(DirectlyAddressedSet * v) {};
	 /*!
	  * \brief Not implemented since this set is static.
	  *
	  * An invocation to this method has no effect on the set.
	  */
	 virtual void retainAll(DirectlyAddressedSet * v) {};
	 /*!
	  * \brief Not implemented since this set is static.
	  *
	  * An invocation to this method has no effect on the set.
	  */
	 virtual void unionOf(DirectlyAddressedSet * v, DirectlyAddressedSet * w) {};
	 /*!
	  * \brief Not implemented since this set is static.
	  *
	  * An invocation to this method has no effect on the set.
	  */
	 virtual void symDiffOf(DirectlyAddressedSet * v, DirectlyAddressedSet * w) {};
	 /*!
	  * \brief Not implemented since this set is static.
	  *
	  * An invocation to this method has no effect on the set.
	  */
	 virtual void intersectOf(DirectlyAddressedSet * v, DirectlyAddressedSet * w) {};
	 /*!
	  * \brief Not implemented since this set is static.
	  *
	  * An invocation to this method has no effect on the set.
	  */
	 virtual void diffOf(DirectlyAddressedSet * v, DirectlyAddressedSet * w) {};
};

template<typename T>
inline HashBitMapDirectlyAddressedSet<T>::HashBitMapDirectlyAddressedSet(long u, const T * s, const long n) : BitMapDirectlyAddressedSet<T>(u) {
}

template<typename T>
inline T * HashBitMapDirectlyAddressedSet<T>::arrayNode(long i) const {
	return baseT + hash->search(&i);
}

template <typename T>
class ArrayBitMapDirectlyAddressedSetFactory : public Factory<ArrayBitMapDirectlyAddressedSet<T> > {
public:

	ArrayBitMapDirectlyAddressedSet<T> * newInstance(long n) {
		return new ArrayBitMapDirectlyAddressedSet<T>(n);
	};

	ArrayBitMapDirectlyAddressedSet<T> * newInstance(long n, void * handle) {
		return new ArrayBitMapDirectlyAddressedSet<T>(n);
	};

};

template <typename T>
class HashBitMapDirectlyAddressedSetFactory : public Factory<HashBitMapDirectlyAddressedSet<T> > {
public:

	HashBitMapDirectlyAddressedSet<T> * newInstance(long n) {
		return new HashBitMapDirectlyAddressedSet<T>(n);
	};

	HashBitMapDirectlyAddressedSet<T> * newInstance(long n, void * handle) {
		return new HashBitMapDirectlyAddressedSet<T>(n);
	};

};

#endif /* BITMAPDIRECTLYADDRESSEDSET_H_ */
